/**
 * @author Elísa og Ingvar
 * @version 1.0
 * @since 2/10/13
 */
public class Parser {
    private Lexer lex;
    private Token token;

    public Parser() {
    }

    public Parser(Lexer lexer) {
        this.lex = lexer;
    }

    /**
     * Aðalfallið sem sér um að kalla á viðeigandi föll til að athuga hvort strengur sé löglegur
     */
    public void parse(){
        if(lex.hasNext())
            token = lex.nextToken();
        expr();
        System.out.println("PRINT");
        return;
    }

    /**
     * Expr getur gert tvennt: Term eða Term+Expr. Byrjað er að kalla á term() þar sem það á við í báðum tilvikum
     * Svo er athugað hvort næsta stak í strengnum sé +, ef svo er þá er kallað aftur á expr()
     */
    private void expr(){
        term();
        if(token.getTokenCode().equals(Token.TokenCode.PLUS)){
            if(lex.hasNext())
                token = lex.nextToken();
            expr();
            System.out.println("ADD");
        }
        return;
    }

    /**
     * Term getur gert tvennt: Factor eða Factor*Term. Þar sem Factor á við í báðum tilvikum þá er byrjað á því að
     * kalla á factor() fallið. Svo er athugað hvort næsta stak í strengnum sé *, ef svo er þá er kallað aftur á term()
     */
    private void term(){
        factor();
        if (token.getTokenCode().equals(Token.TokenCode.MULT)){
            if(lex.hasNext())
                token = lex.nextToken();
            term();
            System.out.println("MULT");
        }
        return;
    }

    /**
     * Factor getur gert tvennt: breyst í integer tölu eða (Expr). Byrjað er að athuga hvort næsta stak sé int, ef það
     * á við þá er farið úr fallinu, ef það á ekki við er athugað hvort næsta stað sé ( og þaðan kallað á expr()
     * fallið. Tékkað er á hvort ) fylgir, ef hann er ekki á eftir þá er kallað á syntaxError() fallið.
     * Ef hvorki integer né ( er næst þá er kallað á syntaxError() fallið
     */
    private void factor(){

        if(token.getTokenCode().equals(Token.TokenCode.INT)){
            System.out.println("PUSH " + token.getLexeme());
            if(lex.hasNext()){
                token = lex.nextToken();
            }
        }
        else if(token.getTokenCode().equals(Token.TokenCode.LPAREN)){

            if(lex.hasNext())
                token = lex.nextToken();

            expr();

            if (token.getTokenCode().equals(Token.TokenCode.RPAREN)){
                if(lex.hasNext()){
                    token = lex.nextToken();
                }
            }
        }
        else
            syntaxError();
        return;
    }

    /**
     * syntaxError sér um að prenta út villuskilaboð og hætta keyrslu forritsins
     */
    private void syntaxError(){
        System.out.println("Syntax error!");
        System.exit(1);
    }
}